from fastapi import APIRouter, Depends, HTTPException, status
from typing import List, Optional
from sqlalchemy.orm import Session

from app.schemas import schedule, common
from app.db.session import get_db
from app.crud.crud_spider import crud_spider  # 直接导入实例，而不是导入类
# from app.crud.crud_spider import CRUDSpider  # 删除这行
from app.crud.crud_schedule import crud_schedule
from app.services.schedule_service import schedule_service

# 删除这行，因为已经导入了crud_spider实例
# crud_spider = CRUDSpider()

router = APIRouter()
@router.post("/", response_model=schedule.ScheduleRead, status_code=status.HTTP_201_CREATED)
def create_schedule(
    schedule_create: schedule.ScheduleCreate,
    db: Session = Depends(get_db)
):
    """为爬虫创建一个新的定时任务"""
    # 检查爬虫是否存在
    db_spider = crud_spider.get(db, id=schedule_create.spider_id)
    if not db_spider:
        raise HTTPException(status_code=404, detail="爬虫不存在")
    
    # 验证CRON表达式
    try:
        schedule_service.validate_cron(schedule_create.cron_expression)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=f"无效的CRON表达式: {str(e)}")
    
    # 计算下次运行时间
    next_run_at = schedule_service.calculate_next_run(schedule_create.cron_expression)
    
    # 创建定时任务
    schedule_obj = crud_schedule.create(db, obj_in=schedule_create)
    
    # 更新下次运行时间
    crud_schedule.update(db, db_obj=schedule_obj, obj_in={"next_run_at": next_run_at})
    
    # 如果启用，添加到调度器
    if schedule_obj.enabled:
        schedule_service.add_job(schedule_obj)
    
    return schedule_obj

@router.get("/", response_model=List[schedule.ScheduleRead])
def get_schedules(
    spider_id: Optional[str] = None,
    enabled: Optional[bool] = None,
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """获取所有定时任务列表"""
    filters = {}
    if spider_id:
        filters["spider_id"] = spider_id
    if enabled is not None:
        filters["enabled"] = enabled
    
    return crud_schedule.get_multi(db, skip=skip, limit=limit, filters=filters)

@router.get("/{schedule_id}", response_model=schedule.ScheduleRead)
def get_schedule(
    schedule_id: str,
    db: Session = Depends(get_db)
):
    """获取特定定时任务的详细信息"""
    db_schedule = crud_schedule.get(db, id=schedule_id)
    if not db_schedule:
        raise HTTPException(status_code=404, detail="定时任务不存在")
    return db_schedule

@router.put("/{schedule_id}", response_model=schedule.ScheduleRead)
def update_schedule(
    schedule_id: str,
    schedule_update: schedule.ScheduleUpdate,
    db: Session = Depends(get_db)
):
    """更新一个定时任务(如修改CRON表达式、启用/禁用)"""
    db_schedule = crud_schedule.get(db, id=schedule_id)
    if not db_schedule:
        raise HTTPException(status_code=404, detail="定时任务不存在")
    
    # 验证CRON表达式(如果提供)
    if schedule_update.cron_expression:
        try:
            schedule_service.validate_cron(schedule_update.cron_expression)
        except ValueError as e:
            raise HTTPException(status_code=400, detail=f"无效的CRON表达式: {str(e)}")
    
    # 准备更新数据
    update_data = schedule_update.dict(exclude_unset=True)
    
    # 如果更新了CRON表达式，计算下次运行时间
    if schedule_update.cron_expression:
        update_data["next_run_at"] = schedule_service.calculate_next_run(schedule_update.cron_expression)
    
    # 更新数据库
    updated_schedule = crud_schedule.update(db, db_obj=db_schedule, obj_in=update_data)
    
    # 更新调度器中的任务
    if schedule_update.enabled is not None or schedule_update.cron_expression:
        if updated_schedule.enabled:
            schedule_service.update_job(updated_schedule)
        else:
            schedule_service.remove_job(schedule_id)
    
    return updated_schedule

@router.delete("/{schedule_id}", response_model=common.Msg)
def delete_schedule(
    schedule_id: str,
    db: Session = Depends(get_db)
):
    """删除一个定时任务"""
    db_schedule = crud_schedule.get(db, id=schedule_id)
    if not db_schedule:
        raise HTTPException(status_code=404, detail="定时任务不存在")
    
    # 从调度器中移除任务
    schedule_service.remove_job(schedule_id)
    
    # 从数据库中删除
    crud_schedule.remove(db, id=schedule_id)
    
    return {"message": "定时任务删除成功"}